using System;
using System.Diagnostics;
using System.IO;
using System.Threading;
using CS2.CSharp.Parsing;
using CS2.Core;
using CS2.Core.Indexing;
using Lucene.Net.Index;
using Lucene.Net.Store;
using NUnit.Framework;

namespace CS2.Tests
{
    [TestFixture]
    public class IndexingServiceTests : BaseTest
    {
        mutable service : IIndexingService;
        docsDir = @"..\..";
        dummyFile = @"..\..\DummyClassForParseTesting.cs";

        [SetUp]
        public Setup() : void
        {
            service = LoggedIndexingService(IndexingService(RAMDirectory(), array[NemerleCSharpParsingService()]));
        }

        [Test]
        public CanResolve() : void
        {
            Assert.IsNotNull(service);

            Debug.WriteLine(service.GetType());
        }

        [Test]
        public IndexExists() : void
        {
            Assert.IsTrue(IndexReader.IndexExists(service.IndexDirectory));
        }

        [Test]
        public HasFilesWaitingToBeIndexed() : void
        {
            Assert.IsFalse(service.IsWaitingForFilesToBeIndexed);

            service.RequestIndexing(FileInfo(dummyFile));
            service.RequestIndexing(DirectoryInfo(docsDir));

            Thread.Sleep(1000);

            Assert.IsTrue(service.IsWaitingForFilesToBeIndexed);
        }

        [Test]
        public CanIndexFiles() : void
        {
            service.RequestIndexing(FileInfo(dummyFile));
            service.UpdateIndex();

            PrintFileOperations();

            Assert.Greater(service.AddedFilesSinceLastUpdate, 0);
            Assert.AreEqual(0, service.DeletedFilesSinceLastUpdate);

            Assert.IsFalse(service.IsWaitingForFilesToBeIndexed);
        }

        [Test]
        public ShoudlntUpdateAnything() : void
        {
            service.UpdateIndex();

            PrintFileOperations();

            Assert.AreEqual(0, service.AddedFilesSinceLastUpdate);
            Assert.AreEqual(0, service.DeletedFilesSinceLastUpdate);
        }

        [Test]
        public ShouldntIndexAgainTheSameFiles() : void
        {
            service.RequestIndexing(FileInfo(dummyFile));

            service.UpdateIndex();

            service.RequestIndexing(FileInfo(dummyFile));

            service.UpdateIndex();

            PrintFileOperations();

            Assert.AreEqual(0, service.AddedFilesSinceLastUpdate);
            Assert.AreEqual(0, service.DeletedFilesSinceLastUpdate);
        }

        [Test]
        public AreDifferentLastWriteTimes() : void
        {
            def ticks1 = File.GetLastWriteTime(dummyFile).Ticks;

            File.SetLastWriteTime(dummyFile, DateTime.Now);

            def ticks2 = File.GetLastWriteTime(dummyFile).Ticks;

            Assert.AreNotEqual(ticks1, ticks2);
        }

        [Test]
        public ShouldReindexIfFileHasBeenModified() : void
        {
            service.RequestIndexing(FileInfo(dummyFile));
            service.UpdateIndex();

            File.SetLastWriteTime(dummyFile, DateTime.Now);
            service.UpdateIndex();

            PrintFileOperations();

            Assert.AreEqual(1, service.AddedFilesSinceLastUpdate);
            Assert.AreEqual(1, service.DeletedFilesSinceLastUpdate);
        }

        private PrintFileOperations() : void
        {
            Debug.WriteLine("Added files: " + service.AddedFilesSinceLastUpdate);
            Debug.WriteLine("Deleted files: " + service.DeletedFilesSinceLastUpdate);
        }
    }
}